"""
    功能：Z评分模型
    作者：hwang_zhicheng
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False

# 读取上市公司数据
# data_xls_1 = pd.read_excel("白酒上市公司交易额表.xls")
# data_xls_2 = pd.read_excel("白酒上市公司营收.xls")
# data_xls_1 = pd.read_excel("ST+上市公司交易额表.xls")
# data_xls_2 = pd.read_excel("ST+上市公司营收1.xls")
# data_xls_3 = pd.read_excel("ST+财务比率.xls")
# data_xls_1 = pd.read_excel("餐饮1.xls")
# data_xls_2 = pd.read_excel("餐饮2.xls")
# data_xls_3 = pd.read_excel("餐饮4.xls")
# data_xls_1 = pd.read_excel("水利1.xls")
# data_xls_2 = pd.read_excel("水利2.xls")
# data_xls_3 = pd.read_excel("水利3.xls")
data_xls_1 = pd.read_excel("交通_Q3_1.xls")
data_xls_2 = pd.read_excel("交通_Q3_2.xls")
data_xls_3 = pd.read_excel("交通_Q3_3.xls")
# data_xls_1 = pd.read_excel("交通_Q4_1.xls")
# data_xls_2 = pd.read_excel("交通_Q4_2.xls")
# data_xls_3 = pd.read_excel("交通_Q4_3.xls")

# 读取上市公司数据
data_1 = data_xls_1.ix[:,
         ["上市状态_Listedstate"]].values

data_2 = data_xls_2.ix[:,
         ['流动负债合计(元)_Totcurlia', '负债合计(元)_Totlia', '盈余公积(元)_Surres',
          '流动资产合计(元)_Totcurass', '资产总计(元)_Totass', "最新公司全称_Lcomnm", "未分配利润(元)_Retear"]].values

data_3 = data_xls_3.ix[:,
         ['息税前利润_EBIT', '股票市值/总负债(Ⅰ)_MarkValtotdb1']].values

# print("data_2", data_2)
# print(data_2)
# print(data_3)
"""
资本公积(元)_Capsur
所有者权益合计(元)_TotSHE
利润总额(元)_Totalprf
财务费用(元)_Finexp
实收资本(或股本)(元)_Shrcap
"""

# 公司数据

# 公司年份数量
com_num = 2
# 上市状态_Listedstate
State_list = data_1[:, 0]
print("State_list", len(State_list))

# 流动负债合计(元)_Totcurlia
SD_list = data_2[:, 0]
# print(SD_li)
# 负债合计(元)_TotLia
D_list = data_2[:, 1]
# 盈余公积(元)_Surres
Surres_list = data_2[:, 2]
# print("D_list：", D_list)
# 流动资产合计(元)_Totcurass
Totcurass_list = data_2[:, 3]
# 资产总计(元)_Totass
Totass_list = data_2[:, 4]
# 最新公司全称_Lcomnm
Lconnm_list = list(data_2[:, 5][::com_num])
# Lconnm_list.replace("*ST", "ST", inplace=1)
# len(Lconnm_list)
# 未分配利润(元)_Retear
Retear_list = data_2[:, 6]
# 息税前利润_EBIT
EBIT_list = data_3[:, 0]
# 股票市值/总负债(Ⅰ)_MarkValtotdb1
MarkValtotdb1_list = data_3[:, 1]


def Z_count(X):
    """
        功能：计算Z值并返回
    """
    # Z = 0.012 * X[0] + 0.014 * X[1] + 0.033 * X[2] + 0.006 * X[3] + 0.999 * X[4]
    # print("Z_X:", X)
    Z = 0.065 * X[0] + 0.326 * X[1] + 0.01 * X[2] + 0.067 * X[3]
    return Z



def X_count(i):
    """
        功能：计算x1~x5的值
        Z=0.065×Xl+0.326×X2+0.01×X3+0.067×X4
        其中：X1= (营运资产 / 总资产)×100
        X2= 留存收益 / 总资产 = (盈余公积 + 未分配利润)/总资产×100
        X3=税息前利润 / 总资产×100
        X4= 资本市值 / 总负债×100
    """
    x1 = (Retear_list[i] - SD_list[i]) / Totass_list[i] * 100
    x2 = (EBIT_list[i] + Surres_list[i]) / Totass_list[i] * 100
    x3 = EBIT_list[i] / Totass_list[i] * 100
    x4 = MarkValtotdb1_list[i] * 100
    # print("[x1, x2, x3, x4", [x1, x2, x3, x4])
    return [x1, x2, x3, x4]


"""
Z<2.675，借款被划入违约组；
反之，如果Z≥2.675，则借款人被划入非违约组。
当1.81<Z<2.99阿尔特曼发现此时的判断失误比较大，称该重叠区域为未知区Ez
"""


def main():
    """
        主函数
    """
    Company_name = Lconnm_list

    Z_list = []
    number = 0

    for i in range(int(data_1.shape[0])):
        X = X_count(i)
        Z = Z_count(X)

        Z_list.append(Z)
        Z_list_length = len(Z_list)

        # print("Z_list_length = {}".format(Z_list_length))
        # print("i = {}".format(i))

        # print("Z_list = {}".format(Z_list[i - 2: i]))
        #

        # 绘制每一个公司的16-18年的条形图
        if Z_list_length % com_num == 0 and Z_list_length != 0:
            # print("Z_list", Z_list)
            plt_tle = Company_name[number] + "16年到18年Z值统计"
            height_list = Z_list[i - 2: i + 1]
            # 绘制条形图
            rects1 = plt.bar(x=range(1, 6, 2), height=height_list, width=1, alpha=0.8, color='red')
            # plt.ylim(0, 1)  # y轴取值范围
            # 设置x轴坐标点显示
            tick_labels = ["2016", "2017", "2018"]
            # tick_labels = ["2016", "2017"]
            tick_pos = np.arange(1, 7, 2)
            plt.xticks(tick_pos, tick_labels)
            plt.title(plt_tle, size=16)
            plt.xlabel("年份", size=10)
            plt.ylabel("Z值", size=10)
            # plt.legend()     # 设置题注

            for a, b in zip(tick_pos, height_list):
                plt.text(a, b + 0.002, '%.4f' % b, ha='center', va='bottom', fontsize=10)

            plt.show()
            # Z列表初始化
            # Z_list = []
            number += 1

    print("Z_list = {}".format(Z_list))
    predict_list = []
    error_num = 0
    correct_num = 0
    for i in range(len(Z_list)):
        if Z_list[i] >= 1.23:
            predict_list.append("Norm")
        elif Z_list[i] < 1.23:
            predict_list.append("ST")
        else:
            # 当有缺失值无法判断时设置为正常状态
            predict_list.append("Norm")

    # 给标签是*ST的公司转换为ST方便判断
    for i in range(len(State_list)):
        if State_list[i] == "*ST":
            State_list[i] = "ST"

    # print("State_list = {}".format(State_list))
    for i in range(len(predict_list)):
        if predict_list[i] == State_list[i]:
            correct_num += 1
        else:
            error_num += 1

    print("准确率 = {}%".format(correct_num / (correct_num + error_num) * 100))

    # 绘制条形图
    print("predict_list = {}".format(predict_list))
    plt_tle = "预测结果"
    height_list = [correct_num, error_num]
    rects1 = plt.bar(x=range(0, 3, 2), height=height_list, width=1, alpha=0.8, color='red')
    # plt.ylim(0, 1)  # y轴取值范围
    # 设置x轴坐标点显示
    tick_labels = ["correct_num", "error_num"]
    tick_pos = np.arange(0, 3, 2)
    plt.xticks(tick_pos, tick_labels)
    plt.title(plt_tle, size=16)
    plt.xlabel("结果", size=10)
    plt.ylabel("计数", size=10)
    # plt.legend()     # 设置题注

    for a, b in zip(tick_pos, height_list):  # 设置题注
        plt.text(a, b + 0.02, '%.4f' % b, ha='center', va='bottom', fontsize=10)

    plt.show()


if __name__ == '__main__':
    main()

"""
Z<2.675，借款被划入违约组；
反之，如果Z≥2.675，则借款人被划入非违约组。
当1.81<Z<2.99阿尔特曼发现此时的判断失误比较大，称该重叠区域为未知区
"""
